﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ModbusTest.Config;
using System.IO;
using ExcelUtility;
using ExcelUtility.Base;
using System.Diagnostics;
using DevComponents;
using controlArray;
using System.Collections;
using System.Threading.Tasks;

namespace ModbusTest
{
    public partial class frmQuery : Form
    {
        ModuleConfigContainer cfgs;
        List<LogItem> itemsAll = new List<LogItem>();
        List<Control> controls = new List<Control>();
        CountManager _cm = new CountManager();
        FormWait frm = new FormWait();
        public event Action<string> SaveOKevent;
        public frmQuery()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
            cfgs = ModulesConfigTool.Load();
            SaveOKevent += frmQuery_SaveOKevent;
        }

        void frmQuery_SaveOKevent(string obj)
        {
            if (InvokeRequired)
            {
                this.Invoke(new Action<string>(frmQuery_SaveOKevent), new object[] { obj });
                return;
            }
            frm.Hide();
            Process.Start(obj);
        }

        private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {
            if (dateTimePicker1.Value > DateTime.Now)
            {
                dateTimePicker1.Value = DateTime.Now;
            }
            if (dateTimePicker1.Value > dateTimePicker2.Value)
            {
                dateTimePicker2.Value = dateTimePicker1.Value.AddDays(1);
            }
        }

        private void dateTimePicker2_ValueChanged(object sender, EventArgs e)
        {
            if (dateTimePicker2.Value > DateTime.Now)
            {
                dateTimePicker2.Value = DateTime.Now;
            }
            if (dateTimePicker1.Value > dateTimePicker2.Value)
            {
                dateTimePicker1.Value = dateTimePicker2.Value.AddDays(-1);
            }
        }

        private void frmQuery_Load(object sender, EventArgs e)
        {
            dateTimePicker1.Value = DateTime.Today.AddDays(-1);
            dateTimePicker2.Value = DateTime.Today;
            var s = from a in cfgs.Modules select a.Name;
            cboProductName.DataSource = s.ToList();
        }

        private void cboProductName_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateCboStations();
        }

        private void UpdateCboStations()
        {
            var s = from a in cfgs.Modules where a.Name == cboProductName.Text select a;
            if (s.Count() > 0)
            {
                var Modules = s.ToArray();
                var s1 = from b in Modules[0].Specifications select b.PLCLocation;
                List<string> stations = new List<string>();
                foreach (var c in s1)
                {
                    if (stations.Contains(ModuleInfo.testFunctionNames[c - 1]))
                        continue;
                    stations.Add(ModuleInfo.testFunctionNames[c - 1]);
                }
                cboTestStation.DataSource = stations;
            }
        }

        private void btnQuery_Click(object sender, EventArgs e)
        {
            if (cboTestStation.Text != "" && cboProductName.Text != "")
            {
                List<string> FileNames = GetFileNames();
                List<LogItem> itemsall = new List<LogItem>();
                foreach (string FileName in FileNames)
                {
                    List<LogItem> items = GetEntityList(FileName);
                    itemsall.AddRange(items);
                }
                itemsAll = itemsall;
                _cm.NGCount = (uint)(from a in itemsAll where a.item1Result == ("False") || a.item1Result == ("NG") || a.item2Result == ("False") || a.item3Result == ("NG") || a.item3Result == ("False") || a.item1Result == ("NG") select a).Count();
                _cm.OKCount = (uint)itemsAll.Count - _cm.NGCount;
                lblNGqty.Text = _cm.NGCount.ToString();
                lblOKQty.Text = _cm.OKCount.ToString();
                lblTotalQty.Text = _cm.totalCount.ToString();
                lblOKRate.Text = _cm.passRate;
                dataGridView1.AutoGenerateColumns = false;
                dataGridView1.DataSource = new BindingList<LogItem>(itemsAll);
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    for (int i = 0; i < row.Cells.Count; i++)
                    {
                        if (row.Cells[i].Value.ToString().Contains("NG") || row.Cells[i].Value.ToString().Contains("False"))
                        {
                            row.Cells[i].Style.ForeColor = Color.Red;
                        }
                        else if (row.Cells[i].Value.ToString().Contains("OK") || row.Cells[i].Value.ToString().Contains("True"))
                        {
                            row.Cells[i].Style.ForeColor = Color.Green;
                        }
                    }
                }
            }
        }
        private List<LogItem> GetEntityList(string FileName)
        {
            try
            {
                // Create an instance of StreamReader to read from a file.
                // The using statement also closes the StreamReader.
                List<LogItem> lis = new List<LogItem>();
                using (StreamReader sr = new StreamReader(FileName))
                {
                    string line;
                    line = sr.ReadLine();
                    string[] header = line.Split(new char[] { ',' });
                    for (int i = 0; i < dataGridView1.Columns.Count; i++)
                    {
                        dataGridView1.Columns[i].HeaderText = "";
                    }
                        //  dataGridView1.Columns
                        for (int i = 0; i < header.Count() && i < dataGridView1.Columns.Count; i++)
                        {
                            dataGridView1.Columns[i].HeaderText = header[i];
                        }
                    while ((line = sr.ReadLine()) != null)
                    {
                        LogItem li = new LogItem();
                        string[] values = line.Split(new char[] { ',' });
                        if (values.Count() >= 8)
                        {
                            li.Date = values[0];
                            li.Time = values[1];
                            li.item1 = values[2];
                            li.item1Result = values[3];
                            li.item2 = values[4];
                            li.item2Result = values[5];
                            li.item3 = values[6];
                            li.item3Result = values[7];
                            dataGridView1.Columns[6].Visible = true;
                            dataGridView1.Columns[7].Visible = true;
                        }
                        else if (values.Count() >= 6)
                        {
                            li.Date = values[0];
                            li.Time = values[1];
                            li.item1 = values[2];
                            li.item1Result = values[3];
                            li.item2 = values[4];
                            li.item2Result = values[5];
                            li.item3 = "";
                            li.item3Result ="";
                            dataGridView1.Columns[6].Visible = false;
                            dataGridView1.Columns[7].Visible = false;             
                        }
                        lis.Add(li);
                    }
                }
                return lis;
            }
            catch (Exception e)
            {
                // Let the user know what went wrong.
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
                return null;
            }

        }

        private List<string> GetFileNames()
        {
            List<string> fileNames = new List<string>();
            DateTime Date = DateTime.Parse(dateTimePicker1.Value.Date.ToString());
            while (Date <= dateTimePicker2.Value.Date)
            {
                string FileName = string.Format("{0}\\{1}\\{2}\\{3}_{4}_{5}.csv"
                    , LogSaver.LogFolder,
                    cboProductName.Text,
                    cboTestStation.Text,
                    cboProductName.Text,
                    cboTestStation.Text,
                    Date.ToString("yyyy-MM-dd"));
                if (File.Exists(FileName))
                {
                    fileNames.Add(FileName);
                }
                Date = Date.AddDays(1);
            }
            return fileNames;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {

            frm.Show();
            TaskFactory tf = new TaskFactory();
            tf.StartNew(SaveReport);
        }

        private void SaveReport()
        {
            List<LogItem> logItems = itemsAll;//获取数据
            string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "excel.xls"; //获得 EXCEL 模板路径
            SheetFormatterContainer formatterContainers = new SheetFormatterContainer(); //实例化一个模板数据格式化容器

            PartFormatterBuilder partFormatterBuilder = new PartFormatterBuilder();//实例化一个局部元素格式化器
            partFormatterBuilder.AddFormatter("testItem", cboTestStation.Text);//将模板表格中 Title 的值设置为跨越 IT 学员
            partFormatterBuilder.AddFormatter("productName", cboProductName.Text);
            partFormatterBuilder.AddFormatter("T_QTY", lblTotalQty.Text);
            partFormatterBuilder.AddFormatter("O_QTY", lblOKQty.Text);
            partFormatterBuilder.AddFormatter("N_QTY",lblNGqty.Text);
            partFormatterBuilder.AddFormatter("P_RATE", lblOKRate.Text);
            formatterContainers.AppendFormatterBuilder(partFormatterBuilder);//添加到工作薄格式容器中，注意只有添加进去了才会生 效

            CellFormatterBuilder cellFormatterBuilder = new CellFormatterBuilder();//实例化一个单元格格式化器
            cellFormatterBuilder.AddFormatter("T1", this.dataGridView1.Columns[2].HeaderText);
            cellFormatterBuilder.AddFormatter("T2", this.dataGridView1.Columns[4].HeaderText);
            cellFormatterBuilder.AddFormatter("T3", this.dataGridView1.Columns[6].HeaderText);
            cellFormatterBuilder.AddFormatter("T11", this.dataGridView1.Columns[2].HeaderText);
            cellFormatterBuilder.AddFormatter("T12", this.dataGridView1.Columns[4].HeaderText);
            cellFormatterBuilder.AddFormatter("T13", this.dataGridView1.Columns[6].HeaderText);
            if (this.dataGridView1.Columns[6].HeaderText != string.Empty)
            {
                cellFormatterBuilder.AddFormatter("T3V", "判定");
                cellFormatterBuilder.AddFormatter("U13", "上公差");
                cellFormatterBuilder.AddFormatter("L13", "下公差");
            }
            else
            {
                cellFormatterBuilder.AddFormatter("T3V", "");
                cellFormatterBuilder.AddFormatter("U13", "");
                cellFormatterBuilder.AddFormatter("L13", "");
            }
            cellFormatterBuilder.AddFormatter("T11V", lblStd1.Text);
            cellFormatterBuilder.AddFormatter("T12V", lblStd2.Text);
            cellFormatterBuilder.AddFormatter("T13V", lblStd3.Text);
            cellFormatterBuilder.AddFormatter("U11V", lbluf1.Text);
            cellFormatterBuilder.AddFormatter("U12V", lbluf2.Text);
            cellFormatterBuilder.AddFormatter("U13V", lbluf3.Text);
            cellFormatterBuilder.AddFormatter("L11V", lbllf1.Text);
            cellFormatterBuilder.AddFormatter("L12V", lbllf2.Text);
            cellFormatterBuilder.AddFormatter("L13V", lbllf3.Text);
            formatterContainers.AppendFormatterBuilder(cellFormatterBuilder);//添加到工作薄格式容器中，注意只有添加进去了才会生效
            //实例化一个表格格式化器，studentList 本身就是可枚举的无需转换，name 表示的模板表格中第一行第一个单元格要填充 的数据参数名
            TableFormatterBuilder<LogItem> tableFormatterBuilder = new TableFormatterBuilder<LogItem>(logItems, "date");
            tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<LogItem, object>>{
                {"date",r=>r.Date},//将模板表格中 name 对应 Student 对象中的属性 Name
                {"time",r=>r.Time},//将模板表格中 sex 对应 Student 对象中的属性 Sex
                {"v1",r=>r.item1},//将模板表格中 km 对应 Student 对象中的属性 KM
                {"r1",r=>r.item1Result},//将模板表格中 score 对应 Student 对象中的属性 Score
                {"v2",r=>r.item2},//将模板表格中 km 对应 Student 对象中的属性 KM
                {"r2",r=>r.item2Result},//将模板表格中 score 对应 Student 对象中的属性 Score
                {"v3",r=>r.item3},//将模板表格中 km 对应 Student 对象中的属性 KM
                {"r3",r=>r.item3Result},//将模板表格中 score 对应 Student 对象中的属性 Score
            });
            string Begin = dateTimePicker1.Value.ToString("yyyyMMdd");
            string End = dateTimePicker2.Value.ToString("yyyyMMdd");
            string fromto = string.Format("{0}-{1}", Begin, End);

            string SavePath = string.Format("D:/report/{0}/{1}/Report-{2}_{3}_{4}.xls", cboProductName.Text, cboTestStation.Text, cboProductName.Text, cboTestStation.Text, fromto);
            formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);
            if (!Directory.Exists(Path.GetDirectoryName(SavePath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(SavePath));
            }
            string excelPath = ExcelUtility.Export.ToExcelWithTemplate(templateFilePath, "report", formatterContainers, SavePath);
            SaveOKevent(excelPath);
          //  return excelPath;
        }

        private System.Windows.Forms.Control getControlFromName(System.Windows.Forms.Control frm, string controlName, short index, String separator)
        {
            controlName = controlName + separator + index;
            foreach (Control EnumControl in frm.Controls)
            {
                if (string.Compare(EnumControl.Name, controlName, true) == 0)
                {
                    return EnumControl;
                }
            }
            return null;
        }
        private void cboTestStation_SelectedIndexChanged(object sender, EventArgs e)
        {
            var s = from a in cfgs.Modules where a.Name == cboProductName.Items[cboProductName.SelectedIndex].ToString() select a;
            var b = s.ToList()[0];
            string station = cboTestStation.Items[cboTestStation.SelectedIndex].ToString();
            var sub = from c in b.Specifications where c.StationName == station select c;
            foreach (Control Con in panel1.Controls)
            {
                if (!Con.Name.Contains("label"))
                    Con.Text = "";
            }
            var lblItems = getControlArray(panel1, "lblItem", "");
            var lblStds = getControlArray(panel1, "lblStd", "");
            var lblufs = getControlArray(panel1, "lbluf", "");
            var lbllfs = getControlArray(panel1, "lbllf", "");
            var specs = sub.ToList();
            for (int i = 0; i < specs.Count; i++)
            {
                lblItems[i].Text = specs[i].Description;
                if (specs[i].Addr_Standard != 0)
                    lblStds[i].Text = specs[i].StandardValue.ToString("f3");
                else
                    lblStds[i].Text = "-";
                if (specs[i].Addr_Lower != 0)
                    lbllfs[i].Text = specs[i].LowerOffset.ToString("f3");
                else
                    lbllfs[i].Text = "-";
                if (specs[i].Addr_Upper != 0)
                    lblufs[i].Text = specs[i].UpperOffset.ToString("f3");
                else
                    lblufs[i].Text = "-";
            }
        }
        public List<Control> getControlArray(System.Windows.Forms.Control frm, string controlName, string separator)
        {
            //short i;
            short startOfIndex;

            List<Control> alist = new List<Control>();
            string strSuffix;
            short maxIndex = -1;
            foreach (Control EnumControl in frm.Controls)
            {

                startOfIndex = Convert.ToInt16(EnumControl.Name.IndexOf(controlName + separator));
                if (startOfIndex == 0)
                {
                    strSuffix = EnumControl.Name.Substring(controlName.Length);
                    if (IsInteger(strSuffix))
                    {
                        if (Convert.ToInt16(strSuffix) > maxIndex)
                        {
                            maxIndex = Convert.ToInt16(strSuffix);
                        }
                    }
                }
            }
            if (maxIndex > -1)
            {
                for (short j = 0; j <= maxIndex; j++)
                {
                    System.Windows.Forms.Control aControl = getControlFromName(frm, controlName, j, separator);
                    if (!((aControl == null)))
                    {
                        System.Type controlType = aControl.GetType();
                        alist.Add(aControl);

                    }

                }
            }
            return alist;
        }
        private static bool IsInteger(string Value)
        {
            if (Value == "")
            {
                return false;
            }
            foreach (char chr in Value)
            {
                if (!(char.IsDigit(chr)))
                {
                    return false;
                }
            }
            return true;
        }
    }
    public class LogItem
    {
        public string Date { get; set; }
        public string Time { get; set; }
        public string item1 { get; set; }
        public string item1Result { get; set; }
        public string item2 { get; set; }
        public string item2Result { get; set; }
        public string item3 { get; set; }
        public string item3Result { get; set; }
    }
}
